__author__ = 'FutureAdmin'


class SchoolMember:
    """
    面向对象的编程带来的主要好处之一就是代码重用,实现这种重用的方法之一是通过继承的机制.继承完全可以理解成类之间的类型和子类型关系

    假设你想要写一个程序来记录学校之中的教师和学生情况,他们有一些共同属性,比如姓名,年龄和地址,他们也有专有的属性,比如教师的薪水,课程和假期,学生的成绩和学费.

    你可以为教师和学生建立两个独立的类来处理他们,但是这样的话,如果要增加一个新的共有属性,就意味着要在这两个独立的类中增加这个属性.这很快就会显得不实用.

    一个比较好的方法是创建一个共同的类成为SchoolMember,然后让教师和学生的类继承这个共同的类,即他们都是这个类型的子类型,然后我们再为这些子类添加专有的属性.
    实用这种方法有很多优点,如果我们增加/改变了SchoolMember中的任何功能,他会自动的反映到子类型之中,
    例如:你要为教师和学生都增加一个新的身份证字段,那么你只要简单的把它加到SchoolMember类中,
    然后在一个子类型之中做的改动不会影响到别的子类,另外一个优点是你可以吧教师和学生对象都做为SchoolMember对象来使用,这在某些场合特别有用,比如统计学校成员的人数.一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例.这种现象被称为多态.
    另外,我们会发现在重用父类的代码的时候,我们无需在不同的类中重复他,而如果我们使用独立的类的话,我们就不得不这么做了.

    在上述的场合中,SchoolMember类被称为基本类或超类,而Teacher和Student类被称为导出类或子类.







    为了使用继承,我们基本类的名称作为一个元组跟在定义类时的类名称之后,然后我们注意到基本类的__init__方法专门使用self变量调用,这样我们就可以初始化对象的基本类部分.
    这一点十分重要--Python不会自动调用基本类的constructor,你得亲自专门调用它.

    我们还观察到我们在方法调用之前加上类名称前缀,然后把self变量及其他参数传递给他.

    注意,在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student的实例仅仅作为SchoolMember的实例.

    另外,在这个例子中,我们调用子类型的tell方法,而不是SchoolMember类的tell方法,可以这样来理解,Python总是首先查找对应类型的方法,在这个例子中就是如此,如果他不能在导出类中找到对应的方法,他才开始在基本类中逐个查找,基本类是在类定义的时候,在元组之中指明的.

    一个术语的注释-- 如果在继承元组中列了一个以上的类,那么他就被称作多重继承.
    """

    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("Initialized School Member %s." % self.name)

    def tell(self):
        """
        Tell my details
        """
        print("Name: %s , Age: %s" % (self.name, self.age))


class Teacher(SchoolMember):
    """
    Represent a teacher
    """

    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name,age)
        self.salary = salary
        print("Initialized Teacher. %s" % self.name)

    def tell(self):
        SchoolMember.tell(self)
        print("Salary:%d" % self.salary)


class Student(SchoolMember):
    """
    Represent a student
    """

    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks
        print("Initialized Student. %s" % self.name)

    def tell(self):
        SchoolMember.tell(self)
        print("Marks: %d" % self.marks)


t = Teacher("Mrs Shrividya", 40, 30000)
s = Student("Swaroop", 22, 75)